<template>
  <div class="uploader">
    <div class="upload-list" v-if="upload">
      <template v-if="upload.url">
        <m-image-preview
          :src="upload.url"
          @remove="handleImgRemove"
          has-remove
          :has-preview="showPreview"
          width="auto"
        />
      </template>
      <template v-else>
        <Spin class="spin" fix>
          <Icon type="ios-loading" size="18" class="spin-icon-load"></Icon>
          <div style="font-size: 12px">上传中</div>
        </Spin>
      </template>
    </div>
    <Upload
      v-show="!upload"
      ref="upload"
      :show-upload-list="false"
      accept="image/jpg, image/jpeg, image/png"
      :format="format"
      :max-size="maxSize"
      :before-upload="handleImgBeforeUpload"
      :action="uploadUrl"
      type="drag"
      :class="{ 'uploader__comp': true, 'round': round }"
      :style="{ width: `${width}px`, height: `${width}px`, lineHeight: `${width}px` }"
    >
      <div
        class="uploader__preview"
        :style="{ width: `${width}px`, height: `${width}px`, lineHeight: `${width}px` }"
      >
        <Icon type="ios-camera" size="20"></Icon>
      </div>
    </Upload>
    <p v-if="desc" style="line-height: 1; color: #999" class="sub-text">{{ desc }}</p>
  </div>
</template>

<script>
import { baseURL } from "@/utils/http";
import axios from "axios";
import ImagePreview from "./components/ImagePreview";

export default {
  name: "m-uploader",

  components: {
    [ImagePreview.name]: ImagePreview
  },

  props: {
    value: String,

    format: {
      type: Array,
      default() {
        return ["jpg", "jpeg", "png"];
      }
    },

    maxSize: {
      type: Number,
      default: 2048
    },

    desc: String,

    round: Boolean,

    width: {
      type: Number,
      default: 60
    },

    showPreview: {
      type: Boolean,
      default: true
    }
  },

  data: function() {
    return {
      upload: null, // 上传图片列表
      uploadUrl: `${baseURL}/api/admin/upload-img` // 上传地址
    };
  },

  watch: {
    value(newValue, oldValue) {
      if (newValue) {
        if (!this.upload) this.upload = {};
        this.upload.url = newValue;
      } else {
        this.upload = null;
      }
    }
  },

  methods: {
    handleImgBeforeUpload(file) {
      if (file.size > this.maxSize) {
        this.$Notice.warning({
          title: "图片大小超过最大限制",
          desc: `图片大小不得超过${Math.ceil(this.maxSize / 1024)}kb`
        });
        return false;
      }
      // 上传
      this.upload = { name: file.name, url: "" };
      const data = new FormData();
      data.append("file", file);
      axios
        .post(this.uploadUrl, data, {
          "Content-Type": "multipart/form-data",
          Authorization: this.$auth.get().token
        })
        .then(response => {
          const { data: res } = response;
          if (res && res.ok) {
            this.upload.url = res.data.url;
            this.$emit("update:value", res.data.url);
          } else {
            this.$Message.error(`图片上传失败${res.msg ? "，" + res.msg : ""}`);
          }
        })
        .catch(err => {
          this.$Message.error(`图片上传失败，${err.toString()}`);
        });
      return false;
    },

    handleImgRemove() {
      this.upload = null;
      this.$emit("update:value", "");
    }
  }
};
</script>

<style lang="scss">
.uploader {
  display: inline-block;
  vertical-align: middle;
  position: relative;
  top: 6px;

  &__comp {
    display: inline-block;

    &.round {
      .ivu-upload {
        border-radius: 50%;
      }
    }
  }

  &__preview {
    display: inline-block;
  }

  .upload-list {
    display: inline-block;
    width: 198px;
    height: 60px;
    text-align: center;
    line-height: 60px;
    border: 1px solid transparent;
    border-radius: 4px;
    overflow: hidden;
    background: #fff;
    position: relative;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
    margin-right: 4px;

    .upload-list img {
      width: auto;
      height: 100%;
    }

    .spin {
      line-height: 1.2em;
    }

    .spin-icon-load {
      animation: ani-spin 1s linear infinite;
    }
  }
}

@keyframes ani-demo-spin {
  from {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
